Imports System.Runtime.Serialization

Namespace DataStream

    ''' <summary>
    ''' Holds a database of stream logs
    ''' </summary>
    ''' <remarks></remarks>
    <Serializable(), ObfuscationAttribute(Exclude:=True, ApplyToMembers:=True)> _
    Public Class StreamLogDB
        Inherits ObjectModel.KeyedCollection(Of DateTime, StreamLogDBItem)

        Delegate Sub RefreshStream()

        <NonSerialized()> _
        Private StreamChangedEvent As RefreshStream = Nothing

        <NonSerialized()> _
        Private mCurrentStream As StreamLog = Nothing

        Protected Overloads Overrides Function GetKeyForItem(ByVal item As StreamLogDBItem) As Date
            Return item.StartTime
        End Function


        ''' <summary>
        ''' Specifiesa callback function for a log change
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property StreamChangedDelegate() As RefreshStream
            Get
                Return StreamChangedEvent
            End Get
            Set(ByVal value As RefreshStream)
                StreamChangedEvent = value
                StreamChangedEvent.Invoke()
            End Set
        End Property

        ''' <summary>
        ''' Adds a stream log to the current database
        ''' </summary>
        ''' <param name="Log"></param>
        ''' <remarks></remarks>
        Public Shadows Sub Add(ByVal Log As StreamLog)
            Dim logItem As New StreamLogDBItem(Log)
            MyBase.Add(logItem)

        End Sub

        ''' <summary>
        ''' Gets the Database entry for the given key
        ''' </summary>
        ''' <param name="key"></param>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property DBEntries(ByVal key As DateTime) As StreamLogDBItem
            Get
                Return MyBase.Item(key)
            End Get
        End Property
        ''' <summary>
        ''' Gets or Sets the database entry for the given index
        ''' </summary>
        ''' <param name="index"></param>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property DBEntries(ByVal index As Integer) As StreamLogDBItem
            Get
                Return MyBase.Item(index)
            End Get
            Set(ByVal value As StreamLogDBItem)
                MyBase.Item(index) = value
            End Set
        End Property

        ''' <summary>
        ''' Gets or Sets the underlying stream log
        ''' </summary>
        ''' <param name="key"></param>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Default Public Shadows Property Item(ByVal key As DateTime) As StreamLog
            Get
                Dim log As StreamLog = MyBase.Item(key).Log
                ' Ensure Contenuity
                If Not IsNothing(log) Then
                    log.StartTime = key 'MyBase.Item(key).StartTime
                End If
                Return log
            End Get
            Set(ByVal value As StreamLog)
                MyBase.Item(key).Log = value
            End Set
        End Property


        ''' <summary>
        ''' Gets or Sets the underlying stream log
        ''' </summary>
        ''' <param name="index"></param>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Default Public Shadows Property Item(ByVal index As Integer) As StreamLog
            Get
                Return MyBase.Item(index).Log
            End Get
            Set(ByVal value As StreamLog)
                MyBase.Item(index).Log = value
            End Set
        End Property

        ''' <summary>
        ''' Sets the current stream log for editing, this is automaticaly saved 
        ''' on serialization. Good to use this function to access the underlying 
        ''' streams!
        ''' </summary>
        ''' <param name="key"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function SetCurrent(ByVal key As DateTime) As StreamLog
            If MyBase.Contains(key) Then
                mCurrentStream = Item(key)

                If Not mCurrentStream Is Nothing Then
                    ' raise the event of the log has changed
                    If Not IsNothing(Me.StreamChangedEvent) Then
                        Me.StreamChangedEvent.Invoke()
                    End If
                Else
                    MyBase.Remove(key)
                End If
            End If
            Return mCurrentStream
        End Function

        ''' <summary>
        ''' Gets or Sets the current stream
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property CurrentStream() As StreamLog
            Get
                If IsNothing(mCurrentStream) Then
                    mCurrentStream = New DataStream.StreamLog()
                End If
                Return mCurrentStream
            End Get
            Set(ByVal value As StreamLog)
                mCurrentStream = value

                If Not IsNothing(Me.StreamChangedEvent) Then
                    Me.StreamChangedEvent.Invoke()
                End If
            End Set
        End Property

#Region "Serialization things"
        <OnSerializing()> _
        Protected Sub BeforeSerialization(ByVal sc As StreamingContext)
            ' Add or Set the current stream logs bytes
            If Not mCurrentStream Is Nothing Then
                If MyBase.Contains(mCurrentStream.StartTime) Then
                    Me.Item(mCurrentStream.StartTime) = mCurrentStream
                ElseIf mCurrentStream.Count > 0 Then
                    Me.Add(mCurrentStream)
                End If
            End If
        End Sub

        <OnDeserialized()> _
        Protected Sub AfterDeSerialization(ByVal sc As StreamingContext)
            mCurrentStream = New DataStream.StreamLog()
        End Sub
#End Region

    End Class

End Namespace
